package com.bossly.metro.Views;

import android.app.Service;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.util.AttributeSet;
import android.view.View;

import com.bossly.metro.R;

public class CompassView extends View implements SensorEventListener {
	private Paint m_paint = new Paint();
	private Location m_start;
	private Location m_end;
	private Drawable m_compass;
	private Drawable m_pointM;
	private SensorManager m_sensor;

	public CompassView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public CompassView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public CompassView(Context context) {
		super(context);
		init();
	}

	private void init() {
		m_compass = getResources().getDrawable(R.drawable.compass);
		m_compass.setBounds(0, 0, m_compass.getIntrinsicWidth(),
				m_compass.getIntrinsicHeight());

		m_pointM = getResources().getDrawable(R.drawable.metro);

		try {
			Object service = getContext().getSystemService(
					Service.SENSOR_SERVICE);

			if (service != null && service instanceof SensorManager) {
				m_sensor = (SensorManager) service;

				Sensor defSensor = m_sensor
						.getDefaultSensor(Sensor.TYPE_ORIENTATION);

				if (defSensor != null) {
					m_sensor.registerListener(this, defSensor,
							SensorManager.SENSOR_DELAY_FASTEST);
				}
			}
		} catch (Exception e) {
			this.setEnabled(false);
			e.printStackTrace();
		}

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		if (m_compass != null) {
			int w = m_compass.getIntrinsicWidth();
			int h = m_compass.getIntrinsicHeight();

			setMeasuredDimension(resolveSize(w, widthMeasureSpec),
					resolveSize(h, heightMeasureSpec));
		} else {
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		}
	}

	public void setStartLocation(Location start) {
		m_start = start;
		invalidate();
	}

	public void setEndLocation(Location end) {
		m_end = end;
		invalidate();
	}

	private float calcDegree() {
		float degree = 0f;

		if (m_start != null && m_end != null) {
			degree = m_start.bearingTo(m_end);
		}

		return degree;
	}

	float dCompass = 0;

	@Override
	protected void onDraw(Canvas canvas) {
		m_paint.setColor(Color.WHITE);
		m_paint.setStyle(Style.FILL);
		float degree = calcDegree();

		if (m_compass != null) {
			m_compass.draw(canvas);

			if (m_start != null && m_end != null) {
				double radians = Math.toRadians(degree - dCompass - 90);

				int radius = (int) (getHeight() / 2 - m_pointM
						.getIntrinsicWidth() * 2 / 3);
				int x = (int) (Math.cos(radians) * radius + (getWidth() - m_pointM
						.getIntrinsicWidth()) / 2d);
				int y = (int) (Math.sin(radians) * radius + (getHeight() - m_pointM
						.getIntrinsicHeight()) / 2d);

				m_pointM.setBounds(x, y, x + m_pointM.getIntrinsicWidth(), y
						+ m_pointM.getIntrinsicHeight());
				m_pointM.draw(canvas);
			}
		}

		// TODO Auto-generated method stub
		super.onDraw(canvas);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		dCompass = event.values[0];
		invalidate();
	}
}
